#include "Common.fxh"

//#define MSAA 1

#ifdef MSAA
Texture2DMS<float, 4> gDepthTex;
Texture2DMS<float4, 4> gNormal_SpecP_Tex;
Texture2DMS<float4, 4> gDiffuse_SpecI_Tex;
Texture2DMS<float2, 4> gSpecP_Tex;
#else
Texture2D gDepthTex;
Texture2D gNormal_SpecP_Tex;
Texture2D gDiffuse_SpecI_Tex;
Texture2D gSpecP_Tex;
#endif

float2 gGBufferRes;

//return float4(pIn.posD.z * 0.4f, 0, 0, 1);
//float swz = pIn.posH.z;

//if(fcmp(swz, pIn.posD.z)) return float4(1,1,0,1);
//else return float4(1,0,0,1);

//float2 hw = pIn.posD.xy / float2(1024, 600);
//float2 sw = pIn.posH.xy * float2(0.5f, -0.5f) + float2(0.5f, 0.5f);
//if(fcmp(sw.x, hw.x) && fcmp(sw.y, hw.y)) return float4(1,1,0,1);
//else return float4(1,0,0,1);

#ifdef MSAA
void getPixelParamsFromGBufferLoadMS(in uint sampleIndex, in int3 texCoord, out float3 normalV, out float3 diffColor, out float specIntens, out float specPower)
{
	float4 diffAndSpecIntens = gDiffuse_SpecI_Tex.Load(texCoord, sampleIndex);
	diffColor = diffAndSpecIntens.xyz;
	specIntens = diffAndSpecIntens.w;
	
	float2 specPowerRT = gSpecP_Tex.Load(texCoord, sampleIndex);
	specPower = decodeSpecPowerFromUNorm(specPowerRT.x);
	
	//float2 normalXY = gNormal_SpecP_Tex.Sample(gLinearSam, texCoord).xy;
	//float3 normalV = float3(normalXY.xy, -sqrt(1.0f - normalXY.x * normalXY.x - normalXY.y * normalXY.y));

	//normalV = decodeNormal(gNormal_SpecP_Tex.Load(texCoord).xy);
	normalV = gNormal_SpecP_Tex.Load(texCoord, sampleIndex).rgb;
}

float getDepthFromGBufferLoadMS(in uint sampleIndex, in int3 texCoord)
{
	return gDepthTex.Load(texCoord, sampleIndex).r;
}

#else

void getPixelParamsFromGBufferLoad(in int3 texCoord, out float3 normalV, out float3 diffColor, out float specIntens, out float specPower)
{
	float4 diffAndSpecIntens = gDiffuse_SpecI_Tex.Load(texCoord);
	diffColor = diffAndSpecIntens.xyz;
	specIntens = diffAndSpecIntens.w;
	
	float2 specPowerRT = gSpecP_Tex.Load(texCoord);
	specPower = decodeSpecPowerFromUNorm(specPowerRT.x);
	
	//float2 normalXY = gNormal_SpecP_Tex.Sample(gLinearSam, texCoord).xy;
	//float3 normalV = float3(normalXY.xy, -sqrt(1.0f - normalXY.x * normalXY.x - normalXY.y * normalXY.y));

	//normalV = decodeNormal(gNormal_SpecP_Tex.Load(texCoord).xy);
	normalV = gNormal_SpecP_Tex.Load(texCoord).rgb;
}

float getDepthFromGBufferLoad(in int3 texCoord)
{
	return gDepthTex.Load(texCoord).r;
}
#endif

float getDepthFromGBuffer(in float2 texCoord)
{
#ifdef MSAA
	return gDepthTex.Load(int2(texCoord * gGBufferRes), 0).x;
#else
	return gDepthTex.Load(int3(texCoord * gGBufferRes, 0)).x;
#endif
}

float3 getNormalFromGBuffer(in float2 texCoord)
{
#ifdef MSAA
	return gNormal_SpecP_Tex.Load(int2(texCoord * gGBufferRes), 0).xyz;
#else
	return gNormal_SpecP_Tex.Load(int3(texCoord * gGBufferRes, 0)).xyz;
#endif
}

float3 calculateLighting(in float3 viewRayV, in float3 lightDirV, in float3 normalV, in float4 gLightColorAndIntens,
						in float3 diffColor, in float specIntens, in float specPower)
{
	float3 diffuse = saturate(dot(normalV, lightDirV)) * diffColor;

	float3 lightDirReflV = reflect(lightDirV, normalV);
	float specular = pow( saturate(dot(viewRayV, lightDirReflV)), specPower ) * specIntens;

	return gLightColorAndIntens.w * gLightColorAndIntens.xyz * (diffuse + specular.xxx);
}